﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesFile;

namespace hzGis.utils
{
    public class PrjUtils
    {

        public static ISpatialReference createSpatialReference(string prjFilePath)
        {
            ISpatialReferenceFactory spatialReferenceFactory = new SpatialReferenceEnvironment();
            ISpatialReference geographicCoordinateSystem = spatialReferenceFactory.CreateESRISpatialReferenceFromPRJFile(prjFilePath);
            return geographicCoordinateSystem;
        }

        public static IFields CreatFields(IFeatureClass fromFeatureClass, ISpatialReference outRe)
        {
            String shapeFielfName = "Shape";
            IFields fields = new Fields();
            IFieldsEdit pFieldsEdit = fields as IFieldsEdit;
            for (var i = 0; i < fromFeatureClass.Fields.FieldCount; i++)
            {
                IField sourceField = fromFeatureClass.Fields.Field[i];
                if (sourceField.Type != esriFieldType.esriFieldTypeGeometry && sourceField.Type != esriFieldType.esriFieldTypeOID)
                {
                    IField targetField = new Field();
                    IFieldEdit pFieldEdit = targetField as IFieldEdit;
                    pFieldEdit.Length_2 = sourceField.Length;
                    pFieldEdit.Name_2 = sourceField.Name;
                    pFieldEdit.Type_2 = sourceField.Type;
                    pFieldEdit.IsNullable_2 = true;
                    pFieldEdit.AliasName_2 = sourceField.AliasName;
                    pFieldsEdit.AddField(targetField);
                }
                else if (sourceField.Type == esriFieldType.esriFieldTypeGeometry)
                {
                    IField geometryField = new Field();
                    IFieldEdit geometryFieldEdit = geometryField as IFieldEdit;
                    geometryFieldEdit.Name_2 = shapeFielfName;
                    geometryFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
                    IGeometryDef pGeometryDef = new GeometryDef();
                    IGeometryDefEdit pGeometryDefEdit = pGeometryDef as IGeometryDefEdit;
                    pGeometryDefEdit.GeometryType_2 = fromFeatureClass.ShapeType;  //此处可以是点、线、面
                    geometryFieldEdit.GeometryDef_2 = pGeometryDef;
                    pGeometryDefEdit.SpatialReference_2 = outRe;
                    pFieldsEdit.AddField(geometryField);
                }
            }
            return fields;
        }


        public static string Project(IFeatureClass fromFeatureClass, string outPath, string outFileName, ISpatialReference prjRe, ISpatialReference geoRe)
        {
            string message = "";
            try
            {
                IWorkspaceFactory fac = new ShapefileWorkspaceFactory() as IWorkspaceFactory;
                IFeatureWorkspace toSpace = (IFeatureWorkspace)fac.OpenFromFile(outPath, 0);
                IFeatureCursor pFC = fromFeatureClass.Search(null, false);
                if (pFC == null) return message;
                IFeature fromFeature = pFC.NextFeature();
                IFeatureCursor pFeatureCursor = null;
                IFields pFields = CreatFields(fromFeatureClass, prjRe);
                IFeatureClass toFeatureClass = toSpace.CreateFeatureClass(outFileName, pFields, null, null, esriFeatureType.esriFTSimple, "SHAPE", "");
                while (fromFeature != null)
                {
                    IPointCollection toPC = new Polygon();
                    fromFeature.Shape.Project(prjRe);
                    pFeatureCursor = toFeatureClass.Insert(true);
                    IFeatureBuffer pf = toFeatureClass.CreateFeatureBuffer();

                    IFields fromFields = fromFeature.Fields;
                    IFields toFields = pf.Fields;
                    for (int i = 0; i < toFields.FieldCount; i++)
                    {
                        IField field = toFields.get_Field(i);
                        if (field.Name.ToUpper() == "SHAPE" || field.Name.ToUpper() == "OBJECTID" || field.Name.ToUpper() == "SHAPE_LENGTH" || field.Name.ToUpper() == "SHAPE_AREA" || field.Name.ToUpper() == "FID")
                        {
                            continue;
                        }
                        int index = fromFields.FindField(field.Name);
                        if (index == -1)
                        {
                            continue;
                        }
                        object o = fromFeature.get_Value(index);
                        if (o != null)
                            pf.set_Value(i, o);
                    }
                    pf.Shape = fromFeature.Shape;
                    pFeatureCursor.InsertFeature(pf);
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(pf);
                    fromFeature = pFC.NextFeature();
                }
                System.Runtime.InteropServices.Marshal.ReleaseComObject(pFC);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(pFeatureCursor);
            }
            catch (Exception ex)
            {
                message = ex.StackTrace;
            }
            finally
            {
            }
            return message;
        }


        public void ConvertShapefileCoordinateSystem(IFeatureClass fromFeatureClass, string outPath, string outFileName, ISpatialReference sourcePrj, ISpatialReference targetPrj)
        {

        }
    }
}
